home *** CD-ROM | disk | FTP | other *** search
/ Network Supervisor's Toolkit / Network Supervisor's Toolkit.iso / tools / nwtp06 / m1_pep.pas < prev    next >
Pascal/Delphi Source File  |  1996-07-10  |  7KB  |  230 lines

  1. {$X+,V-,B-,I-}
  2. program M1_PEP; { Master / Sender }
  3.  
  4. { Testprogram for the nwPEP unit / NwTP 0.6 API. (c) 1993,1995, R.Spronk }
  5.  
  6. uses dos,crt,nwMisc,nwBindry,nwConn,nwIPX,nwPEP;
  7.  
  8. CONST IOSocket=$5678;           { socket to transmit/receive on }
  9.  
  10. Var ListenECB     :Tecb;        { ECB and header, to listen for acknowledgement }
  11.     ListenPepHdr  :TpepHeader;
  12.  
  13.     SendECB       :Tecb;        { ECB and header, used to send the data }
  14.     SendPepHdr    :TpepHeader;
  15.  
  16.     socket        :word;
  17.  
  18.     SendDataBuffer  :array[1..546] of byte; { SendDataBufferfer for data to be sent }
  19.  
  20.     ListenDataBuffer:array[1..8] of byte;
  21.  
  22.     AckReceived   :boolean;     { set to true within the ListenForAckESR }
  23.  
  24.     SendTransId   :LongInt;     { transactionID. This uniquely identifies
  25.                                   the packet. The slave/receiver has to
  26.                                   reply with the same transactionID in the
  27.                                   header of the acknowledgement. Only if
  28.                                   this number is the same as the transactioID
  29.                                   of the sent packet, the pavket is considered
  30.                                   successfully delivered. }
  31.  
  32.     NewStack:array[1..1024] of word;  { !! used by ESR }
  33.     StackBottom:word;                 { !! used by ESR }
  34.  
  35.     f:file;
  36.  
  37.  
  38. Procedure CheckError(err:boolean; errNbr:word);
  39. begin
  40. if err
  41.  then begin
  42.       CASE errNbr of
  43.        $0100:writeln('IPX needs to be installed.');
  44.        $0200:writeln('Error: can''t locate the spcified username.');
  45.        $0201:begin
  46.               writeln('The specified user has multiple connections.');
  47.               writeln('This demonstation program doesn''t support multiple connections.');
  48.               end;
  49.        $0202:writeln('Error: can''t find the address of the supplied username.');
  50.        $0204:writeln('Transfer aborted after 50 retries.');
  51.        $0205:writeln('Key pressed: Transfer aborted.');
  52.        $0206:writeln('The supplied file couldn''t be found. Please supply full path.');
  53.        $10FE:writeln('Error opening socket: Socket Table Is Full.');
  54.        $10FF:writeln('Error opening socket: Socket is already open.');
  55.       end; {case}
  56.       IPXcloseSocket(IOsocket);
  57.       close(f);
  58.       halt(1);
  59.       end;
  60. end;
  61.  
  62. Function TimeOut(t1,t2:word;n:byte):boolean;
  63. { ticks t2 - ticks t1 > n seconds ? }
  64. Var lt1,lt2:LongInt;
  65. begin
  66. lt2:=t2;
  67. if t1>t2 then lt2:=lt2+$FFFF;
  68. TimeOut:=(lt2-t1)>(n*18);
  69. end;
  70.  
  71.  
  72. {$F+}
  73. Procedure ListenForAckHandler(Var p:TPecb);
  74.  { Interrupts are turned off -and should remain turned off- }
  75. begin
  76. IF (ListenECB.CompletionCode<>0)                      { packet must be suucessfully received.. }
  77.  or (ListenPepHdr.IPXhdr.packetType<>PEP_PACKET_TYPE) { of type PEP.. }
  78.  or (ListenPepHdr.ClientType<>$EA)                    { of client type $EA }
  79.  or (ListenPepHdr.TransactionID<>SendTransId)         { with a correct clientID (of the packet the master sent) }
  80.   then IPXListenForPacket(ListenECB)   { Invalid packet => listen again   }
  81.   else AckReceived:=true;              { valid packet   => ACK received ! }
  82. end;
  83. {$F-}
  84.  
  85. {$F+}
  86. Procedure ListenForAckESR; assembler;
  87. asm { ES:SI are the only valid registers when entering this procedure ! }
  88.     { interrupts are turned off -and should remain turned off- }
  89.     mov dx, seg stackbottom
  90.     mov ds, dx
  91.  
  92.     mov dx,ss  { setup of a new local stack }
  93.     mov bx,sp  { ss:sp copied to dx:bx}
  94.     mov ax,ds
  95.     mov ss,ax
  96.     mov sp,offset stackbottom
  97.     push dx    { push old ss:sp on new stack }
  98.     push bx
  99.  
  100.     push es    { push es:si on stack as local vars }
  101.     push si
  102.     mov  di,sp
  103.  
  104.     push ss    { push address of local ptr on stack }
  105.     push di
  106.     CALL ListenForAckHandler
  107.  
  108.     add sp,4   { skip stack ptr-copy }
  109.     pop bx     { restore ss:sp from new stack }
  110.     pop dx
  111.     mov sp,bx
  112.     mov ss,dx
  113. end;
  114. {$F-}
  115.  
  116.  
  117. Var dest:TinternetworkAddress;
  118.     ticks,ticks2:word;
  119.     retries     :word;
  120.  
  121.     Uname,Fname:string;
  122.     NbrOfConn:byte;
  123.     connList:TconnectionList;
  124.  
  125.     p:byte;
  126.     FileInfo:searchrec;
  127.     FileSize:LongInt;
  128.  
  129. begin
  130. If paramcount<>2
  131.  then begin
  132.       writeln('Usage: M1_PEP <username> <filename>');
  133.       writeln('-The file will be sent to the workstation of the supplied username.');
  134.       writeln('-Run S1_PEP on that workstation to receive the file.');
  135.       halt(1);
  136.       end;
  137. Uname:=ParamStr(1);
  138. UpString(Uname);
  139. NbrOfConn:=0;
  140. GetObjectConnectionNumbers(Uname,OT_USER,NbrOfConn,connList);
  141. CheckError((nwConn.result>0) or (NbrOfConn=0),$200);
  142. CheckError(NbrOfConn>1,$0201);
  143.  
  144. GetInternetAddress(connList[1],dest);
  145. CheckError(nwconn.result>0,$0202);
  146. dest.socket:=IOsocket;
  147.  
  148. Fname:=ParamStr(2);
  149. Assign(f,Fname);
  150. Reset(f);
  151. CheckError(IOresult<>0,$0206);
  152.  
  153.  
  154. IpxInitialize;
  155. CheckError(nwIPX.result>0,$0100);
  156.  
  157. socket:=IOSocket;
  158. IPXopenSocket(Socket,SHORT_LIVED_SOCKET);
  159. CheckError(nwIPX.result>0,$1000+nwIPX.result);
  160.  
  161. { setup listening for ack }
  162. AckReceived:=False;
  163.  
  164. PEPsetupListenECB(Addr(ListenForAckESR),IOsocket,@ListenDataBuffer,8,
  165.                   ListenPepHdr,ListenECB);
  166. IPXListenForPacket(ListenECB);
  167.  
  168. { send initial packet with the name and size of the file to be sent. }
  169. findfirst(Fname,$FF,FileInfo);
  170. Move(FileInfo.size,SendDataBuffer[16],4);
  171. FileSize:=Fileinfo.size;
  172. p:=length(Fname);
  173. while (p>0) and (Fname[p]<>':') and (Fname[p]<>'\')
  174.  do dec(p);
  175. If p>0
  176.  then delete (Fname,1,p);
  177. Move(Fname[0],SendDataBuffer[1],15);
  178.  
  179. PEPsetupSendECB(NIL,IOsocket,dest,@SendDataBuffer[1],512,
  180.                 SendPepHdr,SendECB);
  181. SendTransID:=1;
  182. SendPepHdr.ClientType:=$EA;
  183.  
  184. FileSize:=FileSize+512; { compensate length for information header }
  185.  
  186. While Filesize>0
  187.  do begin
  188.     ackreceived:=false;
  189.     SendPepHdr.TransactionId:=SendTransId;
  190.     IPXsendPacket(SendECB);
  191.     writeln('Packet#',SendTransID,' was sent.');
  192.     while sendECB.InuseFlag<>0
  193.      do IPXrelinquishControl;
  194.  
  195.  
  196.     IPXGetIntervalMarker(ticks);
  197.     retries:=0;
  198.     REPEAT
  199.       IPXrelinquishcontrol;
  200.       IPXGetIntervalMarker(ticks2);
  201.       if (ticks2-ticks)>2
  202.        then begin
  203.             inc(retries);
  204.             writeln('Timeout: resending pkt#',SendTransID);
  205.             PEPsetupSendECB(NIL,IOsocket,dest,@SendDataBuffer[1],512,
  206.                             SendPepHdr,SendECB);
  207.             SendPepHdr.ClientType:=$EA;
  208.             SendPepHdr.TransactionId:=SendTransId;
  209.             IPXsendPacket(SendECB);
  210.             while sendECB.InuseFlag<>0
  211.              do IPXrelinquishControl;
  212.             IPXGetIntervalMarker(ticks);
  213.             end;
  214.       CheckError(retries>50,$0204);
  215.       CheckError(Keypressed,$0205);
  216.     UNTIL AckReceived;
  217.     writeln('Ack ',ListenPepHdr.TransactionID,' was received.');
  218.  
  219.     FileSize:=FileSize-512;
  220.     inc(SendTransID);
  221.     {XXX fill buffer met volgende fileblock }
  222.  
  223.  
  224.     IPXListenForPacket(ListenECB); { start listening for acks again }
  225.     end;
  226.  
  227. IPXcloseSocket(IOsocket);
  228. close(f);
  229.  
  230. end.